package study.springcloud.config.nacos.support.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * （★）RedisConnectionFactory 的动态刷新
 * （1）使用@RefreshScope注解类，@Value注解属性，实现 Redis 参数动态刷新
 * （2）使用@RefreshScope注解方法，@Bean注解方法，实现 RedisConnectionFactory 实例化动态刷新
 * （3）Nacos 配置更新后，只有第一次请求 Redis 时才会执行 RedisConnectionFactory 再次实例化
 * （4）RedisTemplate 实例化不要 @RefreshScope 注解，并且 RedisTemplate 不受动态刷新影响，仅实例化一次
 */
@Slf4j
@Configuration
@RefreshScope
public class _1_RedisConfig {

    @Value("${spring.redis.host:}")
    private String host;
    @Value("${spring.redis.port:}")
    private Integer port;
    @Value("${spring.redis.database:}")
    private Integer database;
    @Value("${spring.redis.password:}")
    private String password;

    @Bean
    @RefreshScope
    public RedisConnectionFactory redisConnectionFactory() {
        //动态刷新一次，实例化一次
        log.info(">>>>>> 实例化 RedisConnectionFactory");

        RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(host, port);
        redisConfig.setDatabase(database);
        redisConfig.setPassword(password);
        /*GenericObjectPoolConfig<Object> poolConfig = new GenericObjectPoolConfig<>();
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWait(Duration.ofSeconds(maxWait));
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMaxTotal(maxActive);
        LettuceClientConfiguration config = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofSeconds(timeout))
                .poolConfig(poolConfig)
                .build();*/
        return new LettuceConnectionFactory(redisConfig);
    }

    @Bean
//    @RefreshScope
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        log.info(">>>>>> 实例化 RedisTemplate");
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //序列化
        StringRedisSerializer strSerializer = new StringRedisSerializer();
        template.setKeySerializer(strSerializer);
        template.setValueSerializer(strSerializer);
        template.setHashKeySerializer(strSerializer);
        template.setHashValueSerializer(strSerializer);
        return template;
    }
}
